'use strict';

import { menuModel } from "../model/menu";
import { ServiceBase } from '../kalend';

class MenuService extends ServiceBase {
    constructor() {
        super(menuModel)
    }

    async create(doc: any) {
        await super.create(doc);
        return this.queryTree();
    }
    async update(doc: any) {
        await super.update(doc._id, doc);
        return this.queryTree();
    }
    async delete(id: any) {
        await super.delete(id);
        return this.queryTree();
    }
    async queryById(id: any) {
        return super.queryById(id);
    }
    async queryTree() {
        let data = await super.queryAll({
            sort: { number: 1 }
        });
        const getTrees = (parentid: any, items: Array<any>) => {
            let nodes = items.filter((item) => {
                if (parentid) {
                    return item.parent && item.parent.toJSON() == parentid;
                } else {
                    return !item.parent;
                }
            });
            nodes = nodes.map((node) => {
                node.childs = getTrees(node._id.toJSON(), items);
                return node;
            });
            return nodes;
        };
        return getTrees(null, data);
    }
    async getTree(selectItems: Array<any>) {
        let data = await super.queryAll({
            sort: { number: 1 }
        });

        data = data.map((item) => {
            if (selectItems && selectItems.length > 0) {
                if (selectItems.find((a) => {
                    return a.toJSON() === item._id.toJSON();
                })) {
                    item.select = true;
                }
            } else {
                item.select = false;
            }
            return item;
        });
        const getTrees = (parentid: any, items: Array<any>, nodeid: String) => {
            let nodes = items.filter((item) => {
                if (parentid) {
                    return item.parent && item.parent.toJSON() == parentid;
                } else {
                    return !item.parent;
                }
            });
            nodes = nodes.map((node, index) => {
                if (nodeid == '0') {
                    node.key = index + 1 + '';
                } else {
                    node.key = nodeid + (index + 1 + '');
                }

                node.childs = getTrees(node._id.toJSON(), items, node.key);
                if (node.childs && node.childs.length > 0) {
                    const ischid = node.childs.filter((child: any) => {
                        return child.select == true;
                    });
                    if (ischid && ischid.length > 0) {
                        node.select = true;
                    }
                }
                return node;
            });
            return nodes;
        };
        return getTrees(null, data, '0');
    }

    private async all(): Promise<Array<any>> {
        const docs = await this.queryAll({
            sort: { number: 1 }
        });
        return docs.map((item) => {
            let result: any = item;
            if (result._id) {
                result._id = result._id.toJSON();
            }
            if (result.parent) {
                result.parent = result.parent.toJSON();
            }
            return result;
        });
    }

    private getMenuItems = (parentId: String, menus: Array<any>) => {

        let items: Array<any> = [];
        let childs: Array<any>;

        childs = menus.filter((menu) => {
            let filter: Boolean;
            if (parentId) {
                filter = menu && menu.parent && menu.parent === parentId;
            } else {
                filter = menu && menu.parent === null;
            }
            return filter;
        });

        for (let child of childs) {
            let item: any = {
                id: child._id,
                key: child.key,
                name: child.name,
                url: child.url
            };
            const citems = this.getMenuItems(item.id, menus);
            if (citems && citems.length > 0) {
                item.items = citems;
            }

            items.push(item);
        }
        return items;
    };



    async tree() {
        return this.getMenuItems(null, await this.all());
    }
    private getMenuItemsSimple = (parentId: String, rfullmenus: Array<any>) => {
        let treemenus = [];
        let childs = rfullmenus.filter((menu) => {
            let filter: Boolean;
            if (parentId) {
                filter = menu && menu.parent && menu.parent === parentId;
            } else {
                filter = menu && menu.parent === null;
            }
            return filter;
        });
        for (let child of childs) {
            const id = child._id;
            let item: any = {
                key: child.key,
                name: child.name,
                url: child.url,
                icon: child.icon
            };

            const citems = this.getMenuItemsSimple(id, rfullmenus);
            if (citems && citems.length > 0) {
                item.items = citems;
            }
            treemenus.push(item);
        }
        return treemenus;
    };
    async getUserMenuTreeByRights(rights: Array<any>) {
        /**获取 当前菜单的所有节点包含父亲节点 */
        let get_RMS = (mid: String, menus: Array<any>): Array<String> => {
            let items = [mid];
            let item = menus.find((item) => { return item._id === mid; });
            let parent = item ? item.parent : null;
            if (parent) {
                items = items.concat(get_RMS(parent, menus));
            }
            return items;
        };

        const menus = await this.all();

        /**当前角色所有的菜单 包含付节点 */

        let rmenuIds: Array<String> = [];
        for (let item of rights) {
            rmenuIds = rmenuIds.concat(get_RMS(item.menu, menus));
        }
        let rmenus = menus.filter((item) => {
            return rmenuIds.some((ri) => { return ri === item._id; });
        });
        return this.getMenuItemsSimple(null, rmenus);
    };
    async queryalls(){
        return this.queryAll();
    }
}

export const menuService = new MenuService();

class MenuTreeFull {
    id: String;
    key?: String;
    name: String;
    url?: String;
    icon?: String;
    items?: Array<MenuTreeFull>;
}